package com.plian.system.service.pm.property.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.plian.Tools.CollectionUtil;
import com.plian.Tools.DateUtil;
import com.plian.Tools.pagedata.PageData;
import com.plian.system.dao.bt.baseinfo.BaseInfoDao;
import com.plian.system.dto.pm.property.PropertyChartDTO;
import com.plian.system.entity.pm.property.Property;
import com.plian.system.entity.pm.property.PropertyBasics;
import com.plian.system.entity.pm.property.PropertyChange;
import com.plian.system.entity.pm.property.PropertyOut;
import com.plian.system.mapper.pm.property.PropertyBasicsMapper;
import com.plian.system.mapper.pm.property.PropertyChangeMapper;
import com.plian.system.mapper.pm.property.PropertyMapper;
import com.plian.system.mapper.pm.property.PropertyOutMapper;
import com.plian.system.service.pm.property.IPropertyChartService;
import com.plian.system.service.sys.orgzation.IOrgService;
import com.plian.system.vo.pm.property.TypeQuantityChange;
import com.plian.system.vo.report.*;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: TODO
 * @Author: Take-off
 * @Date: 2023/5/23 1:27 PM
 * @Param
 * @return
 * @Version: 1.0
 **/
@Service
@AllArgsConstructor
@Slf4j
public class PropertyChartServiceImpl implements IPropertyChartService {
    private PropertyBasicsMapper basicsMapper;

    private PropertyMapper propertyMapper;

    private PropertyChangeMapper propertyChangeMapper;

    private PropertyOutMapper propertyOutMapper;

    private BaseInfoDao baseInfoDao;

    private IOrgService orgService;

    @Override
    public PieChartVO getOrgTypeCake(PropertyChartDTO dto)  {
        PieChartVO pieChartVO = new PieChartVO();
        List<PieValueVO> pieValueVOS = new ArrayList<>();
        pieChartVO.setData(pieValueVOS);
        //获取指定月份的产权子集集合
        List<PropertyBasics> chlidList = getChildListByMonth(dto.getMonth(), dto.getProId());
        if (CollectionUtil.isNotEmpty(chlidList)){
            //根据出资关系切分
            Map<String, List<PropertyBasics>> mapByRelation = chlidList.stream().filter(m -> Optional.ofNullable(m.getStateFundedRelation()).isPresent()).collect(Collectors.groupingBy(PropertyBasics::getStateFundedRelation));
            try {
                //获取名字
                List<PageData> findbycodes = baseInfoDao.findbyParentid("126");
                for (PageData pageData:findbycodes){
                    String code = pageData.getString("code");
                    //名字和类型
                    PieValueVO orgTypeCake = new PieValueVO();
                    orgTypeCake.setCode(code);
                    orgTypeCake.setName(pageData.getString("name"));
                    //数量
                    List<PropertyBasics> propertyBasics = mapByRelation.get(code);
                    if (CollectionUtil.isNotEmpty(propertyBasics)){
                        orgTypeCake.setValue(propertyBasics.size());
                    }else {
                        orgTypeCake.setValue(0);
                    }

                    pieValueVOS.add(orgTypeCake);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return pieChartVO;
    }

    @Override
    public PieChartVO getProOrderCake(PropertyChartDTO dto)  {
        PieChartVO pieChartVO = new PieChartVO();
        List<PieValueVO> pieValueVOS = new ArrayList<>();
        pieChartVO.setData(pieValueVOS);
        //获取指定月份的产权子集集合
        List<PropertyBasics> chlidList = getChildListByMonth(dto.getMonth(), dto.getProId());
        if (CollectionUtil.isNotEmpty(chlidList)){
            //根据等级关系切分
            Map<String, List<PropertyBasics>> mapByOrgGradation = chlidList.stream().filter(m -> Optional.ofNullable(m.getOrgGradation()).isPresent()).collect(Collectors.groupingBy(PropertyBasics::getOrgGradation));
            int one =CollectionUtil.isNotEmpty(mapByOrgGradation.get("001001")) ? mapByOrgGradation.get("001001").size() :0 ;
            int two =CollectionUtil.isNotEmpty(mapByOrgGradation.get("001002")) ? mapByOrgGradation.get("001002").size() :0 ;
            int three =CollectionUtil.isNotEmpty(mapByOrgGradation.get("001003")) ? mapByOrgGradation.get("001003").size() :0 ;
            pieValueVOS.add(PieValueVO.builder().name("一级").value(one).build());
            pieValueVOS.add(PieValueVO.builder().name("二级").value(two ).build());
            pieValueVOS.add(PieValueVO.builder().name("三级").value(three).build());
            int count = chlidList.size() - one - two - three;
            pieValueVOS.add(PieValueVO.builder().name("四级及以下").value(count).build());
        }
        return pieChartVO;
    }

    @Override
    public PieChartVO getNatureCake(PropertyChartDTO dto){
        PieChartVO pieChartVO = new PieChartVO();
        List<PieValueVO> pieValueVOS = new ArrayList<>();
        pieChartVO.setData(pieValueVOS);
        //获取指定月份的产权子集集合
        List<PropertyBasics> chlidList = getChildListByMonth(dto.getMonth(), dto.getProId());
        if (CollectionUtil.isNotEmpty(chlidList)){
            //根据等级关系切分
            Map<String, List<PropertyBasics>> mapByNature = chlidList.stream().filter(m -> Optional.ofNullable(m.getNature()).isPresent()).collect(Collectors.groupingBy(PropertyBasics::getNature));
            pieValueVOS.add(PieValueVO.builder().name("境内").value(CollectionUtil.isNotEmpty(mapByNature.get("0")) ? mapByNature.get("0").size() :0 ).build());
            pieValueVOS.add(PieValueVO.builder().name("境外").value(CollectionUtil.isNotEmpty(mapByNature.get("1")) ? mapByNature.get("1").size() :0 ).build());
            pieValueVOS.add(PieValueVO.builder().name("合伙人").value(CollectionUtil.isNotEmpty(mapByNature.get("2")) ? mapByNature.get("2").size() :0 ).build());
        }
        return pieChartVO;
    }

    @Override
    public TypeQuantityChange getProperChangeLine(PropertyChartDTO dto){
        TypeQuantityChange typeQuantityChange = new TypeQuantityChange();
        //折线图
        ChartsVO chartsVO = new ChartsVO();
        //x轴
        List<XAxisVO> xAxisVOList = new ArrayList<>();
        XAxisVO xAxisVO = new XAxisVO();
        List<String> xAxisVOData = new ArrayList<>();
        xAxisVO.setData(xAxisVOData);
        xAxisVOList.add(xAxisVO);
        chartsVO.setXAxis(xAxisVOList);
        //值
        List<SeriesVO> seriesVOList = new ArrayList<>();
        chartsVO.setSeries(seriesVOList);
        //穿透Id
        List<String> ids = new ArrayList<>();
        chartsVO.setIds(ids);
        //结束时间
        Date endTime =getEndTime(dto.getMonth());
        //开始时间
        Date startTime = getStartTime(dto.getMonth());

        //切分时间
        List<String> dates = DateUtil.findDates(1, startTime,endTime);
        xAxisVO.setData(dates);

        //获取时间内的产权子集集合
        List<PropertyBasics> chlidList = getChildListByMonth(dto.getMonth(), dto.getProId());
        //新增产权
        List<Property> propertyList = propertyMapper.selectList(new LambdaQueryWrapper<Property>().eq(Property::getStatus, 3)
                .ge(Property::getCreateTime, startTime).le(Property::getCreateTime, endTime));
        if (CollectionUtil.isNotEmpty(propertyList)){
            typeQuantityChange.setAddNumber(propertyList.size());
        }else {
            typeQuantityChange.setAddNumber(0);
        }
        //变动
        List<PropertyChange> propertyChanges = propertyChangeMapper.selectList(new LambdaQueryWrapper<PropertyChange>().eq(PropertyChange::getStatus, 3)
                .ge(PropertyChange::getCreateTime, startTime).le(PropertyChange::getCreateTime, endTime));
        if (CollectionUtil.isNotEmpty(propertyChanges)){
            typeQuantityChange.setChangeNumber(propertyChanges.size());
        }else {
            typeQuantityChange.setChangeNumber(0);
        }
        //注销
        List<PropertyOut> propertyOuts = propertyOutMapper.selectList(new LambdaQueryWrapper<PropertyOut>().eq(PropertyOut::getStatus, 3)
                .ge(PropertyOut::getCreateTime, startTime).le(PropertyOut::getCreateTime, endTime));
        if (CollectionUtil.isNotEmpty(propertyOuts)){
            typeQuantityChange.setCancellationNumber(propertyOuts.size());
        }else {
            typeQuantityChange.setCancellationNumber(0);
        }

        if (CollectionUtil.isNotEmpty(propertyList)){
            SeriesVO seriesVO = SeriesVO.builder().name("数量").type("line").build();
            seriesVOList.add(seriesVO);
            List<Object> data = new ArrayList<>();
            seriesVO.setData(data);
            //根据时间获取节点
            for (String date:dates){
                //转换成时间,当月最后一天
                Date parse = DateUtil.parse(date, DateUtil.PATTERN_MONTH);
                Date lastTime = DateUtil.minusDays(DateUtil.plusMonths(parse, 1), 1);
                //获取产权Id
                int value = (int)propertyList.stream().filter(m -> (m.getCreateTime().compareTo(lastTime)) < 0).count();
                //获取之后注销的产权
                long outValue = propertyOuts.stream().filter(m -> (m.getCreateTime().compareTo(lastTime)) > 0).count();
                data.add(value + outValue);
            }
            typeQuantityChange.setChartsVO(chartsVO);
        }
        return typeQuantityChange;
    }

    @Override
    public ChartsVO getProperChangeBar(PropertyChartDTO dto){
        //折线图
        ChartsVO chartsVO = new ChartsVO();
        //x轴
        List<XAxisVO> xAxisVOList = new ArrayList<>();
        XAxisVO xAxisVO = new XAxisVO();
        List<String> xAxisVOData = new ArrayList<>();
        xAxisVO.setData(xAxisVOData);
        xAxisVOList.add(xAxisVO);
        chartsVO.setXAxis(xAxisVOList);
        //值
        List<SeriesVO> seriesVOList = new ArrayList<>();
        chartsVO.setSeries(seriesVOList);
        //穿透Id
        List<String> ids = new ArrayList<>();
        chartsVO.setIds(ids);
        //结束时间
        Date endTime =getEndTime(dto.getMonth());
        //开始时间
        Date startTime = getStartTime(dto.getMonth());

        //切分时间
        List<String> dates = DateUtil.findDates(1, startTime,endTime);
        xAxisVO.setData(dates);


        List<PropertyBasics> chlidList = getChildListByMonth(dto.getMonth(), dto.getProId());
        if (CollectionUtil.isNotEmpty(chlidList)){
            List<String> proIds = chlidList.stream().map(PropertyBasics::getId).collect(Collectors.toList());
            //新增产权
            List<Property> propertyList = propertyMapper.selectList(new LambdaQueryWrapper<Property>().eq(Property::getStatus, 3)
                    .ge(Property::getCreateTime, startTime).le(Property::getCreateTime, endTime));

            //变动
            List<PropertyChange> propertyChanges = propertyChangeMapper.selectList(new LambdaQueryWrapper<PropertyChange>().eq(PropertyChange::getStatus, 3)
                    .ge(PropertyChange::getCreateTime, startTime).le(PropertyChange::getCreateTime, endTime));

            //注销
            List<PropertyOut> propertyOuts = propertyOutMapper.selectList(new LambdaQueryWrapper<PropertyOut>().eq(PropertyOut::getStatus, 3)
                    .ge(PropertyOut::getCreateTime, startTime).le(PropertyOut::getCreateTime, endTime));


            if (CollectionUtil.isNotEmpty(propertyList)){
                SeriesVO seriesVO = SeriesVO.builder().name("新增").type("bar").build();
                seriesVOList.add(seriesVO);
                List<Object> data = new ArrayList<>();
                seriesVO.setData(data);
                //根据时间获取节点
                for (String date:dates){
                    //转换成时间,当月最后一天
                    Date parse = DateUtil.parse(date, DateUtil.PATTERN_MONTH);
                    Date lastTime = DateUtil.minusDays(DateUtil.plusMonths(parse, 1), 1);
                    //获取产权Id
                    int value = (int)propertyList.stream().filter(m -> (m.getCreateTime().compareTo(lastTime)) < 0 && (m.getCreateTime().compareTo(parse)) >= 0).count();
                    data.add(value );
                }
            }
            if (CollectionUtil.isNotEmpty(propertyChanges)){
                SeriesVO seriesVO = SeriesVO.builder().name("变动").type("bar").build();
                seriesVOList.add(seriesVO);
                List<Object> data = new ArrayList<>();
                seriesVO.setData(data);
                //根据时间获取节点
                for (String date:dates){
                    //转换成时间,当月最后一天
                    Date parse = DateUtil.parse(date, DateUtil.PATTERN_MONTH);
                    Date lastTime = DateUtil.minusDays(DateUtil.plusMonths(parse, 1), 1);
                    //获取产权Id
                    int value = (int)propertyChanges.stream().filter(m -> (m.getCreateTime().compareTo(lastTime)) < 0 && (m.getCreateTime().compareTo(parse)) >= 0).count();
                    data.add(value );
                }
            }
            if (CollectionUtil.isNotEmpty(propertyOuts)){
                SeriesVO seriesVO = SeriesVO.builder().name("注销").type("bar").build();
                seriesVOList.add(seriesVO);
                List<Object> data = new ArrayList<>();
                seriesVO.setData(data);
                //根据时间获取节点
                for (String date:dates){
                    //转换成时间,当月最后一天
                    Date parse = DateUtil.parse(date, DateUtil.PATTERN_MONTH);
                    Date lastTime = DateUtil.minusDays(DateUtil.plusMonths(parse, 1), 1);
                    //获取产权Id
                    int value = (int)propertyOuts.stream().filter(m -> (m.getCreateTime().compareTo(lastTime)) < 0 && (m.getCreateTime().compareTo(parse)) >= 0).count();
                    data.add(value );
                }
            }
        }
        return chartsVO;
    }

    /**
     * 获取指定月份的产权子集集合（包括子集）
     * @param monthString 月份 yyyy-MM
     * @param proId 产权Id
     * @return  产权集合
     */
//    private List<PropertyBasics> getChildListByMonth(String monthString,String proId){
//
//        Date date =getEndTime(monthString);
//        //企业总数
//        List<PropertyBasics> propertyBasics = basicsMapper.selectList(new LambdaQueryWrapper<PropertyBasics>().eq(PropertyBasics::getStatus, 3)
//                .le(PropertyBasics::getAicRegDate, DateUtil.format(date,DateUtil.PATTERN_DATE)));
//        propertyBasics.addAll(getPartnerListToData(null,date));
//        //获取proId
//        List<PropertyBasics> collect = propertyBasics.stream().filter(m -> proId.equals(m.getId())).collect(Collectors.toList());
//
//        //生成子集
//        List<PropertyBasics> chlidList = getChlidList(proId, propertyBasics, null);
//        if (CollectionUtil.isNotEmpty(collect)){
//            PropertyBasics basic = collect.get(0);
//            if (! orgService.checkIsGzw(basic.getOrgId())){
//                chlidList.add(basic);
//            }
//        }
//        return chlidList;
//    }

    private List<PropertyBasics> getChildListByMonth(String monthString,String proId){
        Date date =getEndTime(monthString);
        //企业总数
        PropertyBasics basics = basicsMapper.selectById(proId);

            return basicsMapper.selectList(new LambdaQueryWrapper<PropertyBasics>().eq(PropertyBasics::getStatus, 3)
                    .le(PropertyBasics::getCreateTime, DateUtil.format(date,DateUtil.PATTERN_DATE)).likeRight(PropertyBasics::getPropertyCode,basics.getPropertyCode())
                    .ne(PropertyBasics::getId,basics.getId()));


    }

    /**
     * 获取合伙人产权
     * @param startTime
     * @param endTime
     * @return
     */
    private List<PropertyBasics> getPartnerListToData(Date startTime,Date endTime){
        LambdaQueryWrapper<PropertyBasics> wrapper = new LambdaQueryWrapper<PropertyBasics>()
                .eq(PropertyBasics::getStatus, 3).eq(PropertyBasics::getNature,2);
        if (Optional.ofNullable(startTime).isPresent()){
            wrapper.ge(PropertyBasics::getEstablishmentDate, DateUtil.format(startTime,DateUtil.PATTERN_DATE));
        }
        if (Optional.ofNullable(endTime).isPresent()){
            endTime = DateUtil.minusSeconds(DateUtil.plusMonths(endTime, 1), 1);
            wrapper.le(PropertyBasics::getEstablishmentDate, DateUtil.format(endTime,DateUtil.PATTERN_DATE));
        }
        //企业总数
        return basicsMapper.selectList(wrapper);
    }

    /**
     * 递归，建立子树形结构
     * @param listAll 数据列表
     * @param pid 父id
     * @return
     */
    public List<PropertyBasics> getChlidList(String pid, List<PropertyBasics> listAll, List<PropertyBasics> list) {
        List<PropertyBasics> varList=new ArrayList<>();
        if(list==null){
            list=new ArrayList<>();
        }
        for (PropertyBasics propertyBasics:listAll) {
            //子集
            List<PropertyBasics> l = new ArrayList<>();
            //添加子集
            if(propertyBasics.getParentId().equals(pid)){
                l.add(propertyBasics);
            }
            //递归添加子集
            if ( l.size() > 0) {
                for (PropertyBasics data : l) {
                    getChlidList(data.getId(),listAll,list);
                    varList.add(data);
                }
            }
        }
        list.addAll(varList);
        return  list;
    }

    /**
     * @Description:  获取当月最后一天的时间
     * @Author: Take-off
     * @Date: 2:34 PM 2023/5/23
     * @Param: [monthString]
     * @return: java.util.Date
     **/
    private Date getEndTime(String monthString){
        //构造月底的时间
        Date month = DateUtil.parse(monthString, DateUtil.PATTERN_MONTH);
        //加一个月减1秒
        return DateUtil.minusSeconds(DateUtil.plusMonths(month, 1), 1);
    }

    /**
     * @Description:  往前倒退5个月获取当前时间
     * @Author: Take-off
     * @Date: 2:51 PM 2023/5/23
     * @Param: [monthString]
     * @return: java.util.Date
     **/
    private Date getStartTime(String monthString){
        //构造月底的时间
        Date month = DateUtil.parse(monthString, DateUtil.PATTERN_MONTH);
        //加一个月减1秒
        return DateUtil.minusMonths(month, 5);
    }
}
